package pay.weixin.utils;

import pay.weixin.bean.WXPayRefund;
import pay.weixin.config.Unifiedorder;

import javax.net.ssl.HttpsURLConnection;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;


/**
 * post提交xml格式的参数
 * Jahnke
 * 2017年1月3日 21:33:17
 */
public class HttpXmlUtils {

    /**
     * 开始post提交参数到接口
     * 并接受返回
     *
     * @param url
     * @param xml
     * @param method
     * @param contentType
     * @return
     */
    public static String xmlHttpProxy(String url, String xml, String method, String contentType) {
        InputStream is = null;
        OutputStreamWriter os = null;

        try {
            URL _url = new URL(url);
            HttpURLConnection conn = (HttpURLConnection) _url.openConnection();
            conn.setDoInput(true);
            conn.setDoOutput(true);
            conn.setRequestProperty("Content-type", "text/xml");
            conn.setRequestProperty("Pragma:", "no-cache");
            conn.setRequestProperty("Cache-Control", "no-cache");
            conn.setRequestMethod("POST");
            os = new OutputStreamWriter(conn.getOutputStream());
            os.write(new String(xml.getBytes(contentType)));
            os.flush();

            //返回值
            is = conn.getInputStream();
            return getContent(is, "utf-8");
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (os != null) {
                    os.close();
                }
                if (is != null) {
                    is.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * 解析返回的值
     *
     * @param is
     * @param charset
     * @return
     */
    public static String getContent(InputStream is, String charset) {
        String pageString = null;
        InputStreamReader isr = null;
        BufferedReader br = null;
        StringBuffer sb = null;
        try {
            isr = new InputStreamReader(is, charset);
            br = new BufferedReader(isr);
            sb = new StringBuffer();
            String line = null;
            while ((line = br.readLine()) != null) {
                sb.append(line + "\n");
            }
            pageString = sb.toString();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (is != null) {
                    is.close();
                }
                if (isr != null) {
                    isr.close();
                }
                if (br != null) {
                    br.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            sb = null;
        }
        return pageString;
    }

    /**
     * 构造xml参数
     *
     * @param unifiedorder
     * @return
     */
    public static String xmlInfo(Unifiedorder unifiedorder) {
        //构造xml参数的时候，至少又是个必传参数
        if (unifiedorder != null) {
            StringBuffer bf = new StringBuffer();
            bf.append("<xml>");

            bf.append("<appid><![CDATA[");
            bf.append(unifiedorder.getAppid());
            bf.append("]]></appid>");

            bf.append("<mch_id><![CDATA[");
            bf.append(unifiedorder.getMch_id());
            bf.append("]]></mch_id>");

            bf.append("<nonce_str><![CDATA[");
            bf.append(unifiedorder.getNonce_str());
            bf.append("]]></nonce_str>");

            bf.append("<sign><![CDATA[");
            bf.append(unifiedorder.getSign());
            bf.append("]]></sign>");

            bf.append("<body><![CDATA[");
            bf.append(unifiedorder.getBody());
            bf.append("]]></body>");

            bf.append("<detail><![CDATA[");
            bf.append(unifiedorder.getDetail());
            bf.append("]]></detail>");

            bf.append("<attach><![CDATA[");
            bf.append(unifiedorder.getAttach());
            bf.append("]]></attach>");

            bf.append("<out_trade_no><![CDATA[");
            bf.append(unifiedorder.getOut_trade_no());
            bf.append("]]></out_trade_no>");

            bf.append("<total_fee><![CDATA[");
            bf.append(unifiedorder.getTotal_fee());
            bf.append("]]></total_fee>");

            bf.append("<spbill_create_ip><![CDATA[");
            bf.append(unifiedorder.getSpbill_create_ip());
            bf.append("]]></spbill_create_ip>");

            bf.append("<time_start><![CDATA[");
            bf.append(unifiedorder.getTime_start());
            bf.append("]]></time_start>");

            bf.append("<time_expire><![CDATA[");
            bf.append(unifiedorder.getTime_expire());
            bf.append("]]></time_expire>");

            bf.append("<notify_url><![CDATA[");
            bf.append(unifiedorder.getNotify_url());
            bf.append("]]></notify_url>");

            bf.append("<trade_type><![CDATA[");
            bf.append(unifiedorder.getTrade_type());
            bf.append("]]></trade_type>");


            bf.append("</xml>");
            return bf.toString();
        }

        return "";
    }

    //退款xml
    public static String getRefundXmlInfo(WXPayRefund refund) {
        //构造xml参数的时候，至少又是个必传参数
        if (refund != null) {
            StringBuffer bf = new StringBuffer();
            bf.append("<xml>");

            bf.append("<appid>");
            bf.append(refund.getAppid());
            bf.append("</appid>");

            bf.append("<mch_id>");
            bf.append(refund.getMch_id());
            bf.append("</mch_id>");

            bf.append("<nonce_str>");
            bf.append(refund.getNonce_str());
            bf.append("</nonce_str>");


            bf.append("<op_user_id>");
            bf.append(refund.getOp_user_id());
            bf.append("</op_user_id>");
//
//            bf.append("<transaction_id><![CDATA[");
//            bf.append(refund.getTransaction_id());
//            bf.append("]]></transaction_id>");

            bf.append("<out_refund_no>");
            bf.append(refund.getOut_refund_no());
            bf.append("</out_refund_no>");


            bf.append("<out_trade_no>");
            bf.append(refund.getOut_trade_no());
            bf.append("</out_trade_no>");


            bf.append("<refund_fee>");
            bf.append(refund.getRefund_fee());
            bf.append("</refund_fee>");

            bf.append("<total_fee>");
            bf.append(refund.getTotal_fee());
            bf.append("</total_fee>");


            bf.append("<sign>");
            bf.append(refund.getSign());
            bf.append("</sign>");

            bf.append("</xml>");
            return bf.toString();
        }

        return "";
    }

    /**
     * 公众号
     *
     * @param unifiedorder
     * @return
     */
    public static String getGZHXmlInfo2(Unifiedorder unifiedorder) {
        //构造xml参数的时候，至少又是个必传参数
        if (unifiedorder != null) {
            StringBuffer bf = new StringBuffer();
            bf.append("<xml>");

            bf.append("<appid><![CDATA[");
            bf.append(unifiedorder.getAppid());
            bf.append("]]></appid>");

            bf.append("<attach><![CDATA[");
            bf.append(unifiedorder.getAttach());
            bf.append("]]></attach>");

            bf.append("<body><![CDATA[");
            bf.append(unifiedorder.getBody());
            bf.append("]]></body>");

            bf.append("<detail><![CDATA[");
            bf.append(unifiedorder.getDetail());
            bf.append("]]></detail>");

            bf.append("<mch_id><![CDATA[");
            bf.append(unifiedorder.getMch_id());
            bf.append("]]></mch_id>");

            bf.append("<nonce_str><![CDATA[");
            bf.append(unifiedorder.getNonce_str());
            bf.append("]]></nonce_str>");

            bf.append("<notify_url><![CDATA[");
            bf.append(unifiedorder.getNotify_url());
            bf.append("]]></notify_url>");

            bf.append("<openid><![CDATA[");
            bf.append(unifiedorder.getOpenid());
            bf.append("]]></openid>");

            bf.append("<out_trade_no><![CDATA[");
            bf.append(unifiedorder.getOut_trade_no());
            bf.append("]]></out_trade_no>");

            bf.append("<spbill_create_ip><![CDATA[");
            bf.append(unifiedorder.getSpbill_create_ip());
            bf.append("]]></spbill_create_ip>");

            bf.append("<time_expire><![CDATA[");
            bf.append(unifiedorder.getTime_expire());
            bf.append("]]></time_expire>");

            bf.append("<time_start><![CDATA[");
            bf.append(unifiedorder.getTime_start());
            bf.append("]]></time_start>");

            bf.append("<total_fee><![CDATA[");
            bf.append(unifiedorder.getTotal_fee());
            bf.append("]]></total_fee>");

            bf.append("<trade_type><![CDATA[");
            bf.append(unifiedorder.getTrade_type());
            bf.append("]]></trade_type>");

            bf.append("<sign><![CDATA[");
            bf.append(unifiedorder.getSign());
            bf.append("]]></sign>");

            bf.append("</xml>");

            return bf.toString();
        }

        return "";
    }


    /**
     * 公众号
     *
     * @param unifiedorder
     * @return
     */
    public static String getGZHXmlInfo(Unifiedorder unifiedorder) {
        //构造xml参数的时候，至少又是个必传参数
        if (unifiedorder != null) {
            StringBuffer bf = new StringBuffer();
            bf.append("<xml>");

            bf.append("<appid>");
            bf.append(unifiedorder.getAppid());
            bf.append("</appid>");

            bf.append("<attach>");
            bf.append(unifiedorder.getAttach());
            bf.append("</attach>");

            bf.append("<body>");
            bf.append(unifiedorder.getBody());
            bf.append("</body>");

            bf.append("<detail>");
            bf.append(unifiedorder.getDetail());
            bf.append("</detail>");

            bf.append("<mch_id>");
            bf.append(unifiedorder.getMch_id());
            bf.append("</mch_id>");

            bf.append("<nonce_str>");
            bf.append(unifiedorder.getNonce_str());
            bf.append("</nonce_str>");

            bf.append("<notify_url>");
            bf.append(unifiedorder.getNotify_url());
            bf.append("</notify_url>");

            bf.append("<openid>");
            bf.append(unifiedorder.getOpenid());
            bf.append("</openid>");

            bf.append("<out_trade_no>");
            bf.append(unifiedorder.getOut_trade_no());
            bf.append("</out_trade_no>");

            bf.append("<spbill_create_ip>");
            bf.append(unifiedorder.getSpbill_create_ip());
            bf.append("</spbill_create_ip>");

            bf.append("<time_expire>");
            bf.append(unifiedorder.getTime_expire());
            bf.append("</time_expire>");

            bf.append("<time_start>");
            bf.append(unifiedorder.getTime_start());
            bf.append("</time_start>");

            bf.append("<total_fee>");
            bf.append(unifiedorder.getTotal_fee());
            bf.append("</total_fee>");

            bf.append("<trade_type>");
            bf.append(unifiedorder.getTrade_type());
            bf.append("</trade_type>");

            bf.append("<sign>");
            bf.append(unifiedorder.getSign());
            bf.append("</sign>");

            bf.append("</xml>");

            return bf.toString();
        }

        return "";
    }


    /**
     * post请求并得到返回结果
     *
     * @param requestUrl
     * @param requestMethod
     * @param output
     * @return
     */
    public static String httpsRequest(String requestUrl, String requestMethod, String output) {
        try {
            URL url = new URL(requestUrl);
            HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setUseCaches(false);
            connection.setRequestMethod(requestMethod);
            if (null != output) {
                OutputStream outputStream = connection.getOutputStream();
                outputStream.write(output.getBytes("UTF-8"));
                outputStream.close();
            }
            // 从输入流读取返回内容
            InputStream inputStream = connection.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            String str = null;
            StringBuffer buffer = new StringBuffer();
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            bufferedReader.close();
            inputStreamReader.close();
            inputStream.close();
            inputStream = null;
            connection.disconnect();
            return buffer.toString();
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        return "";
    }

    /**
     * 返回给微信的消息
     *
     * @param return_code
     * @param return_msg
     * @return
     */
    /*<xml>
    <return_code><![CDATA[SUCCESS]]></return_code>
    <return_msg><![CDATA[OK]]></return_msg>
    </xml>*/
    public static String backWeixin(String return_code, String return_msg) {
        StringBuffer bf = new StringBuffer();
        bf.append("<xml>");

        bf.append("<return_code><![CDATA[");
        bf.append(return_code);
        bf.append("]]></return_code>");

        bf.append("<return_msg><![CDATA[");
        bf.append(return_msg);
        bf.append("]]></return_msg>");

        bf.append("</xml>");
        return bf.toString();
    }

    /**
     * 获取二维码链接
     *
     * @param xmlData
     * @return
     */
    public synchronized static String getCodeUrl(String url, String method, String xmlData) {
        String resXml = null;
        try {
            resXml = HttpXmlUtils.httpsRequest(url, "POST", xmlData);
            System.out.println("resXml:" + resXml);
        } catch (Exception e1) {
            e1.printStackTrace();
        }

        String code_url = "";
        Map<String, String> map;
        try {
            map = XMLUtils.doXMLParse(resXml);
            Object returnCode = map.get("return_code");
            if ("SUCCESS".equals(returnCode)) {
                Object resultCode = map.get("result_code");
                if ("SUCCESS".equals(resultCode)) {
                    code_url = map.get("code_url").toString();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
        return code_url;
    }

    public static String toQueryXml(HashMap<String, String> params) {
        StringBuilder sb = new StringBuilder();
        sb.append("<xml>");
        for (String key : params.keySet()) {
            sb.append("<" + key + ">");
            sb.append(params.get(key));
            sb.append("</" + key + ">");
        }
        sb.append("</xml>");

//		System.out.println("查询订单："+sb.toString());

        return sb.toString();
    }
}